home *** CD-ROM | disk | FTP | other *** search
/ HAM Radio 1997 / HAM Radio 1997.iso / vcls / wsanet8a / wsanet / src / net.c < prev    next >
C/C++ Source or Header  |  1996-04-08  |  32KB  |  1,324 lines

  1. /* Net.C - Generic FIFO queue routines for WSNetC
  2. */
  3. #include "WSANet.H"
  4. #include "Version.H"
  5. #include "NetClnt.H"
  6. #include "NetSrvr.H"
  7. #include <string.h>
  8.  
  9. WSADATA wsaData;
  10.  
  11. static char szError[256];
  12.  
  13. #ifdef DEBUG_BUILD
  14. VOID DEBUGIO(LPSTR lpString)
  15. {
  16.  if(!lpString) return;
  17.  wsprintf((LPSTR)szError, (LPSTR)"IO: %s\n\r", lpString);
  18.  OutputDebugString( (LPSTR)szError );
  19. }
  20. #else
  21. #define DEBUGIO( parm )
  22. #endif /* DEBUG_BUILD */
  23.  
  24.  
  25. /* BOOL netStartup(VOID);
  26.     Purpose: To do the nitty gritty net I/O
  27.     Given:   Nothing.
  28.     Returns: TRUE if everything is OK
  29. */
  30. BOOL netStartup(VOID)
  31. {
  32.  WORD wVersionRequested;
  33.  
  34.  DEBUGIO((LPSTR)"netStartup() - Begin");
  35.  
  36.     // Initialize our WinSock.DLL
  37.  wVersionRequested=WSA_VERSION_NEEDED;
  38.  if(WSAStartup(wVersionRequested, (LPWSADATA)&wsaData))
  39.  {
  40.   DEBUGIO((LPSTR)"netStartup() - BAD WINSOCK VERSION!");
  41.   return(FALSE);
  42.  }
  43.  if((LOBYTE(wsaData.wVersion)!=1) ||
  44.     (HIBYTE(wsaData.wVersion)!=1))
  45.  {
  46.   WSACleanup();
  47.   DEBUGIO((LPSTR)"netStartup() - BAD WINSOCK VERSION!");
  48.   return(FALSE);
  49.  }
  50.  DEBUGIO((LPSTR)"netStartup() - End");
  51.  return(TRUE);
  52. } /* netStartup() */
  53.  
  54.  
  55. /* VOID netCleanup(VOID);
  56.     Purpose: To cleanup after ourselves
  57. */
  58. VOID netCleanup(VOID)
  59. {
  60.  DEBUGIO((LPSTR)"netCleanup()");
  61.  WSACleanup();
  62. } /* netCleanup() */
  63.  
  64.  
  65. /* BOOL netCloseSocket(HWND, SOCKET);
  66.     Purpose: To gracefully close a socket
  67. */
  68. BOOL netCloseSocket(HWND hWnd, SOCKET sSocket)
  69. {
  70.  BOOL bDontLinger;
  71.  
  72.  DEBUGIO((LPSTR)"netCloseSocket() - Begin");
  73.  
  74.  bDontLinger = TRUE;
  75.  if((sSocket) && (sSocket != SOCKET_ERROR))
  76.  {
  77.   if(hWnd) WSAAsyncSelect(sSocket, hWnd,0, 0);
  78.   setsockopt(sSocket,
  79.              SOL_SOCKET, SO_DONTLINGER, (char FAR *)&bDontLinger,
  80.              sizeof(bDontLinger));
  81.   closesocket(sSocket);
  82.  }
  83.  
  84.  DEBUGIO((LPSTR)"netCloseSocket() - End");
  85.  return(FALSE);
  86. }
  87.  
  88.  
  89. /* VOID netConnect(HCTL);
  90.     Purpose:    To decentralize the connect setup code.
  91. */
  92. BOOL netConnect(HCTL hCtl, SOCKET sSocket)
  93. {
  94.  LPNETCLIENT lpNetClient;
  95.  int iSendTempSize = DEFAULT_SENDSIZE,
  96.      iRecvTempSize = DEFAULT_RECVSIZE;
  97.  int iInt = sizeof(iSendTempSize);
  98.  HWND hWnd;
  99.  
  100.  DEBUGIO((LPSTR)"netConnect() - Begin");
  101.  
  102.  lpNetClient=(LPNETCLIENT)VBDerefControl(hCtl);
  103.  
  104.  getsockopt(sSocket, SOL_SOCKET, SO_RCVBUF, (LPSTR)&iRecvTempSize,
  105.             (int FAR *)&iInt);
  106.  getsockopt(sSocket, SOL_SOCKET, SO_SNDBUF, (LPSTR)&iSendTempSize,
  107.             (int FAR *)&iInt);
  108.  
  109.  iSendTempSize = max( iSendTempSize, lpNetClient->sSendSize );
  110.  iRecvTempSize = max( iRecvTempSize, lpNetClient->sRecvSize );
  111.  
  112.     // Destroy any existing Temporary buffer space
  113.  if(lpNetClient->hRecvTemp!=0)
  114.  {
  115.   GlobalUnlock(lpNetClient->hRecvTemp);
  116.   GlobalFree(lpNetClient->hRecvTemp);
  117.  }
  118.  
  119.  if(lpNetClient->hSendTemp!=0)
  120.  {
  121.   GlobalUnlock(lpNetClient->hSendTemp);
  122.   GlobalFree(lpNetClient->hSendTemp);
  123.  }
  124.  
  125.   // Set new size for temporary space
  126.  lpNetClient->sRecvTempSize=(SHORT)iRecvTempSize;
  127.  lpNetClient->sSendTempSize=(SHORT)iSendTempSize;
  128.  
  129.   // Allocate the temporary space
  130.  lpNetClient->hRecvTemp=GlobalAlloc(GMEM_ZEROINIT | GMEM_MOVEABLE,
  131.                                     iRecvTempSize);
  132.  lpNetClient->hSendTemp=GlobalAlloc(GMEM_ZEROINIT | GMEM_MOVEABLE,
  133.                                     iSendTempSize);
  134.  lpNetClient->lpRecvTemp=GlobalLock(lpNetClient->hRecvTemp);
  135.  lpNetClient->lpSendTemp=GlobalLock(lpNetClient->hSendTemp);
  136.  
  137.   // Lock and load the receive buffer
  138.  lpNetClient->hRecvBuffer=GlobalAlloc(GMEM_ZEROINIT | GMEM_MOVEABLE,
  139.                                       lpNetClient->sRecvSize);
  140.  if(lpNetClient->hRecvBuffer)
  141.     lpNetClient->lpRecvBuffer=GlobalLock(lpNetClient->hRecvBuffer);
  142.  
  143.   // Lock and load the send buffer
  144.  lpNetClient->hSendBuffer=GlobalAlloc(GMEM_ZEROINIT | GMEM_MOVEABLE,
  145.                                       lpNetClient->sSendSize);
  146.  if(lpNetClient->hSendBuffer)
  147.     lpNetClient->lpSendBuffer=GlobalLock(lpNetClient->hSendBuffer);
  148.  
  149.  hWnd = VBGetControlHwnd(hCtl);
  150.  
  151.  DEBUGIO((LPSTR)"netConnect() - Calling WSAAsyncSelect()");
  152.  
  153.  WSAAsyncSelect(sSocket, hWnd, CM_NETACTIVITY,
  154.                 FD_READ | FD_WRITE | FD_CLOSE);
  155.  
  156.   // Flag connection!
  157.  lpNetClient->bConnect=TRUE;
  158.  
  159.  VBSetControlProperty(hCtl, IPROP_NETCLIENT_ERRORNUMBER, (LONG)0);
  160.  
  161.   // Let application do what it needs to do.
  162.  if(clientFireOnConnect(hCtl))
  163.  {
  164.   DEBUGIO((LPSTR)"netConnect() - End - FireOnConnect() returned non-0!");
  165.   return(TRUE);
  166.  }
  167.  
  168.  DEBUGIO((LPSTR)"netConnect() - End");
  169.  
  170.  return(FALSE);
  171. } /* netConnect() */
  172.  
  173.  
  174. /* VOID netAccept(HCTL, SOCKET);
  175.     Purpose:    To decentralize the server accept code.
  176. */
  177. BOOL netAccept(HCTL hCtl, SOCKET sSocket)
  178. {
  179.  LPNETSERVER lpNetServer;
  180.  ONACCEPTPARMS Parameters;
  181.  SOCKET sNewSocket;
  182.  HLSTR hlPeerAddr;
  183.  LPSTR lpPeerAddr;
  184.  SHORT sRemotePort;
  185.  SOCKADDR_IN saPeer;
  186.  int iPeer = sizeof(saPeer);
  187.  ERR err;
  188.  
  189.  lpNetServer=(LPNETSERVER)VBDerefControl(hCtl);
  190.  
  191.  if(!sSocket) sSocket = lpNetServer->sSocket;
  192.  
  193.  sNewSocket = accept(sSocket, (struct sockaddr FAR *)&saPeer, (LPINT)&iPeer);
  194.  
  195.  if(sNewSocket == INVALID_SOCKET)
  196.  {
  197.   NetServerError(hCtl, WSAGetLastError());
  198.   return(TRUE);
  199.  }
  200.  
  201.  sRemotePort = (SHORT)htons(saPeer.sin_port);
  202.  
  203.  lpPeerAddr=inet_ntoa(saPeer.sin_addr);
  204.  
  205.  if(lpPeerAddr == NULL)
  206.  {
  207.   hlPeerAddr = VBCreateHlstr(NULL, 0);
  208.  }
  209.  else
  210.  {
  211.   hlPeerAddr = VBCreateHlstr(lpPeerAddr, lstrlen(lpPeerAddr));
  212.  }
  213.  
  214.  Parameters.RemotePort = (SHORT FAR *)&sRemotePort;
  215.  Parameters.Socket = (SHORT FAR *)&sNewSocket;
  216.  Parameters.PeerAddr = hlPeerAddr;
  217.  
  218.  err = VBFireEvent(hCtl, IEVENT_NETSERVER_ONACCEPT,
  219.                    (LPVOID)&Parameters);
  220.  if(!err)
  221.  {
  222.   DEBUGIO((LPSTR)"netAccept() - Destroying hlPeerAddr");
  223.   VBDestroyHlstr(hlPeerAddr);
  224.  
  225.     // If the user did a "Socket = 0" or "Socket = -1" then closed the
  226.     // accepted connection (no NetClient was created to handle it)
  227.   if((!sNewSocket)||(sNewSocket==SOCKET_ERROR))
  228.   {
  229.    netCloseSocket((HWND)NULL, sNewSocket);
  230.    DEBUGIO((LPSTR)"netAccept() - Accepted Socket now closed");
  231.   }
  232.   DEBUGIO((LPSTR)"netAccept() - End");
  233.   return(FALSE);
  234.  }
  235.  else
  236.  {
  237.   DEBUGIO((LPSTR)"netAccept() - VBFireEvent() returned non-0!");
  238.   return(TRUE);
  239.  }
  240. } /* netAccept() */
  241.  
  242.  
  243. /* LONG netServerAsyncProc(HWND, HCTL, WPARAM, LPARAM);
  244.     Purpose: To handle asyncronous WinSock server transactions
  245. */
  246. LONG netServerAsyncProc(HCTL hCtl, HWND hWnd, WPARAM wParam, LPARAM lParam)
  247. {
  248.  LPNETSERVER lpNetServer;
  249.  
  250.  lpNetServer=(LPNETSERVER)VBDerefControl(hCtl);
  251.  
  252.  DEBUGIO((LPSTR)"netServerAsyncProc() - Begin");
  253.  
  254.  if(WSAGETSELECTERROR(lParam))
  255.  {
  256.   NetServerError(hCtl, WSAGETSELECTERROR(lParam));
  257.  }
  258.  
  259.  switch(WSAGETSELECTEVENT(lParam))
  260.  {
  261.   /*************** FD_ACCEPT ****************/
  262.   case FD_ACCEPT:
  263.   {
  264.    DEBUGIO((LPSTR)"netServerAsyncProc() - FD_ACCEPT - Begin");
  265.  
  266.    if(lpNetServer->sSocket != (SOCKET)wParam)
  267.    {
  268.     DEBUGIO((LPSTR)"netServerAsyncProc() - FD_ACCEPT - A child socket accept()ed!");
  269.     return(ERR_None);
  270.    }
  271.       // Setup buffers & such
  272.    netAccept(hCtl,(SOCKET)wParam);
  273.  
  274.    DEBUGIO((LPSTR)"netServerAsyncProc() - FD_ACCEPT - End");
  275.    return(ERR_None);
  276.   }
  277.   break; /* FD_ACCEPT */
  278.  
  279.   /*************** DEFAULT ******************/
  280.   default:
  281.   {
  282.    char szError[256];
  283.  
  284.    wsprintf((LPSTR)szError, (LPSTR)"netServerAsyncProc: Unhandled WSA message #%d",
  285.              wParam);
  286.  
  287.    DEBUGIO((LPSTR)szError);
  288.   }
  289.  }
  290.  
  291.  DEBUGIO((LPSTR)"netServerAsyncProc() - End");
  292.  return(0L);
  293. } /* netServerAsyncProc() */
  294.  
  295.  
  296. /* LONG netClientAsyncProc(HWND, HCTL, WPARAM, LPARAM);
  297.     Purpose: To handle asyncronous WinSock client transactions.
  298. */
  299. LONG netClientAsyncProc(HCTL hCtl, HWND hWnd, WPARAM wParam, LPARAM lParam)
  300. {
  301.  LPNETCLIENT lpNetClient;
  302.  
  303.  lpNetClient=(LPNETCLIENT)VBDerefControl(hCtl);
  304.  
  305.  DEBUGIO((LPSTR)"netClientAsyncProc() - Begin");
  306.  
  307.  if(WSAGETSELECTERROR(lParam))
  308.  {
  309.   NetClientError(hCtl, WSAGETSELECTERROR(lParam));
  310.  }
  311.  
  312.  switch(WSAGETSELECTEVENT(lParam))
  313.  {
  314.   /*************** FD_CONNECT ****************/
  315.   case FD_CONNECT:
  316.   {
  317.    DEBUGIO((LPSTR)"netClientAsyncProc() - FD_CONNECT - Begin");
  318.  
  319.       // Setup buffers & such
  320.    netConnect(hCtl,(SOCKET)wParam);
  321.  
  322.    DEBUGIO((LPSTR)"netClientAsyncProc() - FD_CONNECT - End");
  323.    return(ERR_None);
  324.   }
  325.   break; /* FD_CONNECT */
  326.  
  327.  
  328.   /*************** FD_READ ****************/
  329.   case FD_READ:
  330.   {
  331.    int iCount;
  332.  
  333.    DEBUGIO((LPSTR)"netClientAsyncProc() - FD_READ - Begin");
  334.  
  335.    if((!lpNetClient->sSocket) || (lpNetClient->sSocket == SOCKET_ERROR))
  336.    {
  337.     DEBUGIO((LPSTR)"netClientAsyncProc() - FD_READ - End - sSocket is invalid!");
  338.     return(ERR_None);
  339.    }
  340.  
  341.    if(lpNetClient->lpRecvBuffer)
  342.    {
  343.     iCount = netRecvData(hCtl);
  344.    }
  345.    else return(netReturnError( WSAERR_RecvBuffer,
  346.                                WSAERR_RecvBuffer, NULL ));
  347.  
  348.    if(iCount==SOCKET_ERROR)
  349.    {
  350.     int iError;
  351.  
  352.     iError = WSAGetLastError();
  353.     switch(iError)
  354.     {
  355.      case WSAECONNRESET:
  356.       // Peer reset connection
  357.       return(clientFireOnClose(hCtl));
  358.  
  359.      case WSAEINPROGRESS:
  360.      case WSAEWOULDBLOCK:
  361.       return(ERR_None);
  362.  
  363.      default:
  364.       return(NetClientError( hCtl, WSAGetLastError()));
  365.     }
  366.    }
  367.  
  368.    if(iCount==0)
  369.    {
  370.     struct linger lLinger;
  371.  
  372.     DEBUGIO((LPSTR)"netClientAsyncProc() - FD_READ - recv() returned 0! Closing connection.");
  373.  
  374.     lpNetClient=(LPNETCLIENT)VBDerefControl(hCtl);
  375.  
  376.     if(lpNetClient->sSocket != SOCKET_ERROR)
  377.     {
  378.      netCloseSocket(hWnd, lpNetClient->sSocket);
  379.      lpNetClient->bConnect=FALSE;
  380.      lpNetClient->sSocket=(SOCKET)SOCKET_ERROR;
  381.     }
  382.     return(clientFireOnClose(hCtl));
  383.    }
  384.  
  385.       // Did we receive enough to cause an event?
  386.    if(iCount >= (lpNetClient->sRecvThreshold))
  387.    {
  388.     return(clientFireOnRecv(hCtl));
  389.    }
  390.    return(ERR_None);
  391.   } /* FD_READ */
  392.  
  393.  
  394.   /*************** FD_WRITE ***************/
  395.   case FD_WRITE:
  396.   {
  397.    DEBUGIO((LPSTR)"netClientAsyncProc() - FD_WRITE - Begin");
  398.  
  399.    lpNetClient->fCanSend=TRUE;
  400.    if(lpNetClient->sSendCount)
  401.    {
  402.     netSendData(hCtl);
  403.    }
  404.  
  405.    DEBUGIO((LPSTR)"netClientAsyncProc() - FD_WRITE - End");
  406.    return(ERR_None);
  407.   } /* FD_WRITE */
  408.  
  409.  
  410.   /*************** FD_CLOSE ***************/
  411.   case FD_CLOSE:
  412.   {
  413.    struct linger lLinger;
  414.  
  415.    DEBUGIO((LPSTR)"netClientAsyncProc() - FD_CLOSE - Begin");
  416.  
  417.    if(lpNetClient->lpRecvBuffer)
  418.    {
  419.     netRecvData(hCtl);
  420.    }
  421.  
  422.    if(lpNetClient->sSocket != SOCKET_ERROR)
  423.    {
  424.     netCloseSocket(hWnd, lpNetClient->sSocket);
  425.     lpNetClient->bConnect=FALSE;
  426.     lpNetClient->sSocket=(SOCKET)SOCKET_ERROR;
  427.    }
  428.    lpNetClient->bConnect=FALSE;
  429.  
  430.     // Let the user handle what is left over
  431.    clientFireOnRecv(hCtl);
  432.  
  433.     // Let the user handle the closing
  434.    clientFireOnClose(hCtl);
  435.  
  436.    DEBUGIO((LPSTR)"netClientAsyncProc() - FD_CLOSE - End");
  437.    return(ERR_None);
  438.   } /* FD_CLOSE */
  439.  
  440.  
  441.   default:
  442.   {
  443.    char szError[256];
  444.  
  445.    wsprintf((LPSTR)szError, (LPSTR)"netClientAsyncProc: Unknown message #%d",
  446.              wParam);
  447.  
  448.    DEBUGIO((LPSTR)szError);
  449.   }
  450.  }
  451.  
  452.  DEBUGIO((LPSTR)"netClientAsyncProc() - End");
  453.  return(0L);
  454. } /* netClientAsyncProc() */
  455.  
  456.  
  457. /* ERR netSendData(HCTL);
  458.     Purpose: To send data pending in the send queue to the sSocket
  459.     Given:   The VB control handle
  460.     Returns: ERR_None or a VB/Control error
  461. */
  462. ERR netSendData(HCTL hCtl)
  463. {
  464.  char szError[256];
  465.  LPSTR lpBuffer,
  466.        lpWalker,
  467.        lpEnd,
  468.        lpTemp;
  469.  int   iSent,
  470.        iCount;
  471.  SOCKET sSocket;
  472.  LPNETCLIENT lpNetClient;
  473.  
  474.  DEBUGIO((LPSTR)"netSendData() - Begin");
  475.  
  476.  if(!hCtl)
  477.  {
  478.   DEBUGIO((LPSTR)"netSendData() - End - hCtl was 0!");
  479.   return(ERR_None);
  480.  }
  481.  
  482.  lpNetClient=(LPNETCLIENT)VBDerefControl(hCtl);
  483.  
  484.  if(!(lpNetClient->fCanSend))
  485.  {
  486.   DEBUGIO((LPSTR)"netSendData() - End - Can't send data! Waiting for FD_WRITE");
  487.   return(ERR_None);  // No FD_WRITE received yet
  488.  }
  489.  
  490.  iCount=lpNetClient->sSendCount;
  491.  lpBuffer=lpNetClient->lpSendBuffer;
  492.  lpTemp=lpNetClient->lpSendTemp;
  493.  sSocket=lpNetClient->sSocket;
  494.  
  495.  if((!sSocket)||(sSocket == SOCKET_ERROR))
  496.  {
  497.   DEBUGIO((LPSTR)"netSendData() - End - Socket is invalid!");
  498.   return(ERR_None);
  499.  }
  500.  if(!iCount)
  501.  {
  502.   DEBUGIO((LPSTR)"netSendData() - End - Nothing to send!");
  503.   return(ERR_None);
  504.  }
  505.  if(!lpBuffer)
  506.  {
  507.   DEBUGIO((LPSTR)"netSendData() - End - No Send buffer!");
  508.   return(ERR_None);
  509.  }
  510.  
  511.  while(iCount > 0)
  512.  {
  513.   iSent=send(sSocket, lpBuffer, iCount, 0);
  514.  
  515.   if(iSent==SOCKET_ERROR)
  516.   {  // If something was blocking, always try again
  517.    iSent=WSAGetLastError();
  518.    switch(iSent)
  519.    {
  520.     case WSAEWOULDBLOCK:
  521.     {
  522.      MSG Msg;
  523.  
  524.      lpNetClient->fCanSend = FALSE;
  525.      DEBUGIO((LPSTR)"netSendData() - End - Overflow (WSAEWOULDBLOCK) - Waiting for FD_WRITE");
  526.         // Let other applications take over (somehow this is needed)
  527.      PeekMessage(&Msg, NULL, 0, 0, PM_NOREMOVE);
  528.      return(ERR_None);        // Mark that this happened!
  529.     }
  530.  
  531.     case WSAEINPROGRESS:
  532.     {
  533.      DEBUGIO((LPSTR)"netSendData() - End - Non-fatal error (WSAEINPROGRESS)");
  534.      return(ERR_None);        // No real error condition exists
  535.     }
  536.  
  537.     default:
  538.     {
  539.      DEBUGIO((LPSTR)"netSendData() - Fatal error");
  540.      return(NetClientError(hCtl, iSent));
  541.     }
  542.    }
  543.   }
  544.  
  545.   DEBUGIO((LPSTR)"netSendData() - Sent data");
  546.  
  547.   wsprintf((LPSTR)szError,
  548.            (LPSTR)"netSendData() - lpBuffer=%lX iSent=%X iCount=%X",
  549.            lpBuffer, iSent, iCount);
  550.   DEBUGIO((LPSTR)szError);
  551.  
  552.   /*lpWalker=lpBuffer+iSent;
  553.   lpEnd=lpBuffer+iCount;
  554.   while(lpWalker<lpEnd)
  555.   {
  556.    *lpBuffer++=*lpWalker++;
  557.   }
  558. //  lpBuffer[0] = '\0';
  559.   */
  560.  
  561.   iCount-=iSent;
  562.   _fmemmove(lpBuffer, (lpBuffer+iSent), (size_t)iCount);
  563.  
  564.   DEBUGIO((LPSTR)"netSendData() - Copied more to buffer");
  565.  
  566.   lpNetClient->sSendCount=(SHORT)iCount;
  567.  
  568.     // Has threshold been reached?
  569.   if(iCount < lpNetClient->sSendThreshold)
  570.   {
  571.    ERR err;
  572.  
  573.    DEBUGIO((LPSTR)"netSendData() - Threshold reached!");
  574.    clientFireOnSend(hCtl);
  575.    if(!err)
  576.    {    // Refresh all of our local vars.
  577.     lpNetClient=(LPNETCLIENT)VBDerefControl(hCtl);
  578.     iCount=lpNetClient->sSendCount;
  579.     lpBuffer=lpNetClient->lpSendBuffer;
  580.     lpTemp=lpNetClient->lpSendTemp;
  581.     sSocket=lpNetClient->sSocket;
  582.     if((!sSocket) || (sSocket == SOCKET_ERROR))
  583.     {
  584.      DEBUGIO((LPSTR)"netSendData() - End - After firing OnSend(), Socket became invalid");
  585.      return(ERR_None);
  586.     }
  587.    }
  588.    else return(ERR_None);
  589.   }
  590.  }
  591.  
  592.  DEBUGIO((LPSTR)"netSendData() - End");
  593.  return(ERR_None);
  594. } /* netSendData() */
  595.  
  596.  
  597. /* int netRecvData(HCTL);
  598.     Purpose: To recv data pending on a socket and stuff it in the
  599.              recv queue
  600.     Given:   A VB control structure
  601.     Returns: Nothing
  602.     Does:    Magic
  603. */
  604. int netRecvData(HCTL hCtl)
  605. {
  606.  LPSTR lpBuffer,
  607.        lpTemp;
  608.  int   iReceived,
  609.        iCount,
  610.        iSize;
  611.  SOCKET sSocket;
  612.  LPNETCLIENT lpNetClient;
  613.  char szErrors[256];
  614.  
  615.  DEBUGIO((LPSTR)"netRecvData() - Begin");
  616.  
  617.  lpNetClient=(LPNETCLIENT)VBDerefControl(hCtl);
  618.  if(!lpNetClient)
  619.  {
  620.   DEBUGIO((LPSTR)"netRecvData() - VBDerefControl() returned NULL!!! Call in the troops!");
  621.   return(SOCKET_ERROR);
  622.  }
  623.  iCount=lpNetClient->sRecvCount;
  624.  if(iCount==-1) iCount=0;
  625.  lpBuffer=lpNetClient->lpRecvBuffer;
  626.  lpTemp=lpBuffer+iCount;
  627.  iSize=lpNetClient->sRecvSize;
  628.  sSocket=lpNetClient->sSocket;
  629.  
  630.  if(!lpBuffer)
  631.  {
  632.     // Keep the messages coming
  633.   DEBUGIO((LPSTR)"netRecvData() - No receive buffer!");
  634.   recv(lpNetClient->sSocket, NULL, 0, 0);
  635.   DEBUGIO((LPSTR)"netRecvData() - End - non-fatal");
  636.   return(SOCKET_ERROR);
  637.  }
  638.  
  639.  if((!sSocket)||(sSocket==SOCKET_ERROR))
  640.  {
  641.   DEBUGIO((LPSTR)"netRecvData() - End - Socket is not valid!");
  642.   return(SOCKET_ERROR);
  643.  }
  644.  
  645.  DEBUGIO((LPSTR)"netRecvData() - Debugging information");
  646.  
  647.  wsprintf((LPSTR)szErrors, (LPSTR)"netRecvData() - iCount=%d, iSize=%d",
  648.           iCount, iSize);
  649.  DEBUGIO((LPSTR)szErrors);
  650.  
  651.  wsprintf((LPSTR)szErrors, (LPSTR)"netRecvData() - sSocket=%d, lpTemp=%lX",
  652.           sSocket, lpTemp);
  653.  DEBUGIO((LPSTR)szErrors);
  654.  
  655.  if(!lpTemp) return(SOCKET_ERROR);
  656.  
  657.  DEBUGIO((LPSTR)"netRecvData() - Calling recv()");
  658.  
  659.  iReceived=recv(sSocket, lpTemp,
  660.              iSize-iCount, 0);
  661.  
  662.  wsprintf((LPSTR)szErrors, (LPSTR)"netRecvData() - recv()==%d", iReceived);
  663.  DEBUGIO((LPSTR)szErrors);
  664.  
  665.  DEBUGIO((LPSTR)"netRecvData() - Marker #0");
  666.  
  667.  if(iReceived==SOCKET_ERROR)
  668.  {  // If something was blocking, always try again
  669.   iReceived=WSAGetLastError();
  670.   if((iReceived!=WSAEINPROGRESS) &&
  671.      (iReceived!=WSAEWOULDBLOCK))
  672.   {
  673.    DEBUGIO((LPSTR)"netRecvData() - Marker #1");
  674.    NetClientError(hCtl, iReceived);
  675.    DEBUGIO((LPSTR)"netRecvData() - Fatal error");
  676.    return(SOCKET_ERROR);
  677.   }
  678.   DEBUGIO((LPSTR)"netRecvData() - Non-fatal error");
  679.   return(SOCKET_ERROR);
  680.  }
  681.  
  682.  DEBUGIO((LPSTR)"netRecvData() - Marker #2");
  683.  
  684.  if(iReceived==-1)
  685.  {
  686.   DEBUGIO((LPSTR)"netRecvData() - iReceived==-1! Impossible!!!!");
  687.   return(0);
  688.  }
  689.  
  690.  if(!iReceived)
  691.  {
  692.   DEBUGIO((LPSTR)"netRecvData() - iReceived==0! - returning 0");
  693.   return(0);
  694.  }
  695.  
  696.  DEBUGIO((LPSTR)"netRecvData() - Marker #3");
  697.  
  698.  iCount+=iReceived;
  699.  
  700.  lpNetClient->sRecvCount=(SHORT)iCount;
  701.  
  702.  DEBUGIO((LPSTR)"netRecvData() - End");
  703.  
  704.  return(iCount);
  705. } /* netRecvData() */
  706.  
  707.  
  708. /* int putSendData(HCTL, MOLE);
  709.     Purpose: To stuff data into the send queue
  710.     Given:   A VB control structure
  711.              A VB handled string - Not destroyed
  712.     Returns: Send queue size.
  713.     Does:    Magic.
  714. */
  715. int putSendData(HCTL hCtl, MOLE mMole)
  716. {
  717.  LPSTR lpBuffer,
  718.        lpStrEnd,
  719.        lpBufEnd,
  720.        lpWalker,
  721.        lpStr,
  722.        lpTemp;
  723.  LPNETCLIENT lpNetClient;
  724.  int   iSize,
  725.        iCount;
  726.  USHORT uRemaining,
  727.        uStrLen;
  728.  char szErrors[256];
  729.  
  730.  DEBUGIO((LPSTR)"putSendData() - Begin");
  731.  
  732.  if(!hCtl)
  733.  {
  734.   DEBUGIO((LPSTR)"putSendData() - End - hCtl is 0!");
  735.   return(SOCKET_ERROR);
  736.  }
  737.  if(!mMole)
  738.  {
  739.   DEBUGIO((LPSTR)"putSendData() - End - mMole is 0!");
  740.   return(SOCKET_ERROR);
  741.  }
  742.  
  743.  lpNetClient=(LPNETCLIENT)VBDerefControl(hCtl);
  744.  
  745.  iSize=lpNetClient->sSendSize;
  746.  iCount=lpNetClient->sSendCount;
  747.  lpBuffer=lpNetClient->lpSendBuffer;
  748.  lpTemp=lpBuffer+iCount;
  749.  
  750.  if(!lpBuffer)
  751.  {
  752.   DEBUGIO((LPSTR)"putSendData() - No send buffer!");
  753.   return(SOCKET_ERROR);
  754.  }
  755.  
  756.  if(iCount > iSize)
  757.  {
  758.   DEBUGIO((LPSTR)"putSendData() - SendCount is greater than SendSize!");
  759.   return(SOCKET_ERROR);
  760.  }
  761.  
  762.  uRemaining=(USHORT)(iSize-iCount);
  763.  
  764.  uStrLen=VBGetHlstrLen((HLSTR)mMole);
  765.  if(!uStrLen)
  766.  {
  767.   DEBUGIO((LPSTR)"putSendData() - uStrLen = 0!");
  768.   return(0);
  769.  }
  770.  
  771.  wsprintf((LPSTR)szErrors, (LPSTR)"putSendData() - mMole=%X, uStrLen=%X",
  772.           mMole, uStrLen);
  773.  DEBUGIO((LPSTR)szErrors);
  774.  
  775.     // Watch for buffer overflow
  776.  if(uRemaining && uStrLen>uRemaining)
  777.  {
  778.   DEBUGIO((LPSTR)"putSendData() - Trying to make buffer room");
  779.  
  780.   netSendData(hCtl);
  781.  
  782.   DEBUGIO((LPSTR)"putSendData() - Marker #2");
  783.  
  784.   lpNetClient=(LPNETCLIENT)VBDerefControl(hCtl);
  785.   iCount=lpNetClient->sSendCount;
  786.  
  787.   DEBUGIO((LPSTR)"putSendData() - Marker #4");
  788.  
  789.   uRemaining=(USHORT)(iSize-iCount);
  790.  }
  791.  
  792.  if(uRemaining && uStrLen>uRemaining)
  793.  {
  794.   DEBUGIO((LPSTR)"putSendData() - End - Overflow!!!");
  795.   return(SOCKET_ERROR);
  796.  }
  797.  
  798.  DEBUGIO((LPSTR)"putSendData() - Enough room, now filling");
  799.  
  800.  GetMoleName(mMole, lpTemp, iSize - iCount);
  801.  
  802. /* lpStrEnd=lpStr+uStrLen;
  803.  lpBufEnd=lpBuffer+iSize;
  804.  lpWalker=lpTemp;
  805.  while((lpStr<lpStrEnd) && (lpWalker<lpBufEnd))
  806.  {
  807.   *lpWalker++=*lpStr++;
  808.  }
  809.  *lpWalker='\0';
  810. */
  811.  
  812.  iCount+=uStrLen;
  813.  
  814.  lpNetClient=(LPNETCLIENT)VBDerefControl(hCtl);
  815.  lpNetClient->sSendCount=(SHORT)iCount;
  816.  
  817.     // If we can, flush some
  818.  DEBUGIO((LPSTR)"putSendData() - trying to send data out of turn");
  819.  netSendData(hCtl);
  820.  
  821.  DEBUGIO((LPSTR)"putSendData() - End");
  822.  return(uStrLen);
  823. } /* putSendData() */
  824.  
  825.  
  826. /* HLSTR getRecvData(HCTL);
  827.     Purpose: To get a block of data in VB string form from the recv
  828.              queue.
  829.     Given:   VB control handle
  830.     Returns: A VB HLSTR holding the data.
  831.     Note:    This routine receives all or nothing, and it will return
  832.              embedded NULLs that were received.
  833. */
  834. HLSTR getRecvData(HCTL hCtl)
  835. {
  836.  LPSTR lpBuffer;
  837.  int   iCount;
  838.  LPNETCLIENT lpNetClient;
  839.  HLSTR hlReturn;
  840.  
  841.  DEBUGIO((LPSTR)"getRecvData() - Begin");
  842.  
  843.  lpNetClient=(LPNETCLIENT)VBDerefControl(hCtl);
  844.  iCount=lpNetClient->sRecvCount;
  845.  
  846.  if(!iCount)
  847.  {
  848.   DEBUGIO((LPSTR)"getRecvData() - RecvBuffer is logically empty!");
  849.   return(VBCreateHlstr(NULL, 0));
  850.  }
  851.  
  852.  lpBuffer=lpNetClient->lpRecvBuffer;
  853.  
  854.  hlReturn=VBCreateHlstr(lpBuffer, (USHORT)iCount);
  855.  
  856.     // Did the VB string get created?
  857.  if(hlReturn)
  858.  {  // then update the internal count
  859.   lpNetClient=(LPNETCLIENT)VBDerefControl(hCtl);
  860.   lpNetClient->sRecvCount=0;
  861.  }
  862.  
  863.  DEBUGIO((LPSTR)"getRecvData() - End - Cross your fingers");
  864.  return(hlReturn);
  865. } /* getRecvData() */
  866.  
  867.  
  868. /* HSZ getRecvLine(HCTL);
  869.     Purpose: To get a line of data from the queue. Will only return a
  870.              non-null string if it finds the LineDelimiter sequence.
  871.     Given:   A VB control handle
  872.     Returns: A VB Null terminated string - cannot/will-not include
  873.              any nulls (must use getRecvData).
  874. */
  875. HSZ getRecvLine(HCTL hCtl)
  876. {
  877.  LPSTR lpBuffer,
  878.        lpDelim,
  879.        lpEnd,
  880.        lpBufEnd,
  881.        lpWalker,
  882.        lpKeep,
  883.        lpTemp;
  884.  int   iFound,
  885.        iCount,
  886.        iRemaining,
  887.        iSize;
  888.  HSZ   hszDelim;
  889.  HSZ   hszReturn;
  890.  BOOL  bEnd;
  891.  char  cChar;
  892.  LPNETCLIENT lpNetClient;
  893.  
  894.  DEBUGIO((LPSTR)"getRecvLine() - Begin");
  895.  
  896.  cChar='\0';
  897.  lpNetClient=(LPNETCLIENT)VBDerefControl(hCtl);
  898.  
  899.  iCount=lpNetClient->sRecvCount;
  900.  
  901.  if(!iCount)
  902.  {
  903.   DEBUGIO((LPSTR)"getRecvLine() - Logically empty! Returning empty HSZ");
  904.   return(VBCreateHsz((_segment)hCtl, (LPSTR)&cChar));
  905.  }
  906.  
  907.  iSize=lpNetClient->sRecvSize;
  908.  lpBuffer=lpNetClient->lpRecvBuffer;
  909.  
  910.  if(!lpBuffer)
  911.  {
  912.   DEBUGIO((LPSTR)"getRecvLine() - No RecvBuffer!!!");
  913.   return(VBCreateHsz((_segment)hCtl,
  914.                      (LPSTR)&cChar));
  915.  }
  916.  
  917.     // Lock in the delimiter string
  918.  hszDelim=lpNetClient->hszRawLineDelimiter;
  919.  if(hszDelim)
  920.  {
  921.   lpDelim=VBLockHsz(hszDelim);
  922.   if(lpDelim)
  923.   {
  924.    DEBUGIO((LPSTR)"getRecvLine() - RawDelim locked Pointer is valid");
  925.   }
  926.  }
  927.  else
  928.  {
  929.   DEBUGIO((LPSTR)"getRecvLine() - No RawDelim string!");
  930.   lpDelim=NULL;
  931.  }
  932.  lpNetClient=(LPNETCLIENT)VBDerefControl(hCtl);
  933.  
  934.  bEnd=FALSE;
  935.  if(!lpDelim)
  936.  {
  937.   bEnd=TRUE;
  938.  }
  939.  else if(!*lpDelim)
  940.  {
  941.   bEnd=TRUE;
  942.  }
  943.  
  944.  if(bEnd)
  945.  {
  946.   if(hszDelim) VBUnlockHsz(hszDelim);
  947.   DEBUGIO((LPSTR)"getRecvLine() - End - Everything returned! (No delimiter)");
  948.   lpBuffer[iCount]='\0';
  949.   hszReturn=VBCreateHsz((_segment)hCtl, (LPSTR)lpBuffer);
  950.   if(hszReturn)
  951.   {
  952.    lpNetClient=(LPNETCLIENT)VBDerefControl(hCtl);
  953.    lpNetClient->sRecvCount=0;
  954.    return(hszReturn);
  955.   }
  956.   return(VBCreateHsz((_segment)hCtl, (LPSTR)&cChar));
  957.  }
  958.  
  959.  lpBufEnd=lpBuffer+iCount;
  960.  lpTemp=lpBuffer;
  961.  
  962.  DEBUGIO((LPSTR)"getRecvLine() - Searching buffer:");
  963. //DEBUGIO(lpTemp);
  964.  
  965.  while(lpTemp<lpBufEnd)
  966.  {
  967.   //DEBUGIO() replacement on next line
  968. #ifdef DEBUG_BUILD
  969.   OutputDebugString((LPSTR)"*");
  970. #endif // DEBUG_BUILD
  971.  
  972.       // How did a null get in here?!?!
  973.   if(!*lpTemp)
  974.   {
  975.    //DEBUGIO((LPSTR)"Embedded Chr$(0) found in input");
  976.    lpTemp++;
  977.    continue;
  978.   }
  979.  
  980.       // Is there a 1st character match?
  981.   if(*lpDelim==*lpTemp)
  982.   {
  983.    lpKeep=lpTemp;
  984.  
  985.    //DEBUGIO((LPSTR)"First character delimiter match!");
  986.    lpWalker=lpDelim;
  987.       // While the delimiting string continues...
  988.    while(*lpWalker)
  989.    {
  990.       // Walk with the matches, stop if not
  991.     if(*lpWalker==*lpTemp)
  992.     {
  993.      lpWalker++;
  994.      lpTemp++;
  995.     }
  996.     else break;
  997.    }
  998.       // Is the delimiter at it's end?
  999.    if(!*lpWalker)
  1000.    {
  1001.     DEBUGIO((LPSTR)"getRecvLine() - Matched delimiter!");
  1002.     *lpKeep='\0';   // Overwrite first byte of matched delimiter
  1003.     hszReturn=VBCreateHsz((_segment)hCtl, lpBuffer);
  1004.  
  1005.         // If a string was created earlier, return it!
  1006.     if(hszReturn)
  1007.     {
  1008.      DEBUGIO((LPSTR)"getRecvLine() - Successful HSZ created!");
  1009.  
  1010.         // Calculate bytes remaining
  1011.      // 0x0000 <cr> lpKeep       lpBuffer
  1012.      // 0x0001 <lf>
  1013.      // 0x0002            lpTemp
  1014.      iFound = lpTemp-lpBuffer;
  1015.      iCount-=iFound;
  1016.  
  1017.         // Prevent wrap around!!!!
  1018.      if(iCount < 0)
  1019.      {
  1020.       DEBUGIO((LPSTR)"getRecvLine() - Underflow!!!!!");
  1021.       if(hszDelim) VBUnlockHsz(hszDelim);
  1022.       return(VBCreateHsz((_segment)hCtl, (LPSTR)&cChar));
  1023.      }
  1024.  
  1025.      lpNetClient=(LPNETCLIENT)VBDerefControl(hCtl);
  1026.      lpNetClient->sRecvCount=(SHORT)iCount;
  1027.  
  1028.      if(iCount > 0)
  1029.      {
  1030.         // Copy used buffer down to overlap where it was
  1031.       DEBUGIO((LPSTR)"getRecvLine() - DEBUG: _fmemmove()");
  1032.       _fmemmove(lpBuffer, lpTemp, iCount);
  1033.      }
  1034.  
  1035.      DEBUGIO((LPSTR)"getRecvLine() - Returning string");
  1036.      VBUnlockHsz(hszDelim);
  1037.      return(hszReturn);
  1038.     }
  1039.    }
  1040.    else
  1041.    {
  1042.     lpTemp=lpKeep;
  1043.    }
  1044.   }
  1045.   lpTemp++;
  1046.  }
  1047.  
  1048.    // Didn't find the delimiter string
  1049.  VBUnlockHsz(hszDelim);
  1050.  cChar=0;
  1051.  
  1052.  DEBUGIO((LPSTR)"getRecvLine() - End - Nothing returned!");
  1053.  return(VBCreateHsz((_segment)hCtl, (LPSTR)&cChar));
  1054. } /* getRecvLine() */
  1055.  
  1056.  
  1057. // Declare Function NetClientSendBlock Lib "WSNETC.VBX" /
  1058. //      (cControl As NetClient, sString As String) As Integer
  1059. /* int CALLBACK _export NetClientSendBlock(HCTL hCtl, HLSTR);
  1060.     Purpose: To return a "block" string from the recv queue.
  1061.     Given:   The handle of the control to use
  1062.              The string to send
  1063.     Returns: The number of characters sent
  1064. */
  1065. int CALLBACK _export NetClientSendBlock(HCTL hCtl, HLSTR hlStr)
  1066. {
  1067.  DEBUGIO((LPSTR)"NetClientSendBlock()");
  1068.  return(putSendData(hCtl, hlStr));
  1069. } /* NetClientSendBlock() */
  1070.  
  1071.  
  1072. // Declare Function NetClientRecvBlock Lib "WSNETC.VBX" /
  1073. //      (cControl As NetClient, sString As String, iNumber As Integer) As Integer
  1074. /* HLSTR CALLBACK _export NetClientRecvBlock(int);
  1075.     Purpose: To return a "block" string from the recv queue.
  1076.     Given:   A NetClient control
  1077.              A VB String
  1078.              The number of characters to grab, or 0 for everything
  1079.     Returns: 0 if everything went ok, an error if not
  1080. */
  1081. int CALLBACK _export NetClientRecvBlock(HCTL hCtl, HLSTR hlStr, int iNumber)
  1082. {
  1083.  LPNETCLIENT lpNetClient;
  1084.  LPSTR lpBuffer;
  1085.  int iCount;
  1086.  HLSTR hlTemp;
  1087.  ERR err;
  1088.  
  1089.  DEBUGIO((LPSTR)"NetClientRecvBlock() - Begin");
  1090.  
  1091.  lpNetClient=(LPNETCLIENT)VBDerefControl(hCtl);
  1092.  iCount=lpNetClient->sRecvCount;
  1093.  
  1094.  if(iNumber==0) iNumber=iCount;
  1095.  if(iNumber>iCount) iNumber=iCount;
  1096.  
  1097.  hlTemp = hlStr;
  1098.  
  1099.  if(!iCount)
  1100.  {
  1101.   DEBUGIO((LPSTR)"NetClientRecvBlock() - RecvBuffer is logically empty!");
  1102.  
  1103.   VBSetHlstr((LPHLSTR)&hlTemp, NULL, 0);
  1104.   return(0);
  1105.  }
  1106.  
  1107.  lpBuffer=lpNetClient->lpRecvBuffer;
  1108.  
  1109.  err = VBSetHlstr((LPHLSTR)&hlTemp, (LPVOID)lpBuffer, (SHORT)iNumber);
  1110.  if(!err)
  1111.  {
  1112.   lpNetClient=(LPNETCLIENT)VBDerefControl(hCtl);
  1113.   lpNetClient->sRecvCount=(SHORT)(iCount - iNumber);
  1114.  }
  1115.  
  1116.  DEBUGIO((LPSTR)"NetClientRecvBlock() - End - Cross your fingers ;)");
  1117.  return(err);
  1118. } /* NetClientRecvBlock() */
  1119.  
  1120.  
  1121. /* ERR netReturnError(ERR, int, LPSTR);
  1122.     Purpose: To set the text for a VB error, and return
  1123. */
  1124. ERR netReturnError(ERR eError, int iResource, LPSTR lpMessage)
  1125. {
  1126.  static szString[128];
  1127.  
  1128.  DEBUGIO((LPSTR)"netReturnError()");
  1129.     // Resource #0 means use default text for error
  1130.  if(lpMessage == NULL)
  1131.  {
  1132.   if(iResource == 0) return(eError);
  1133.  
  1134.   if(!LoadString(hModDLL, iResource, (LPSTR)szString,
  1135.            sizeof(szString)))
  1136.   {
  1137.    wsprintf((LPSTR)szString, (LPSTR)"Unknown Error #%d: Resource string #%d missing",
  1138.                 eError, iResource);
  1139.   }
  1140.   return(VBSetErrorMessage(eError, (LPSTR)szString));
  1141.  }
  1142.  else
  1143.   return(VBSetErrorMessage(eError, lpMessage));
  1144. } /* netReturnError() */
  1145.  
  1146.  
  1147. /* HSZ GetMoleHsz(HCTL, MOLE);
  1148.     Purpose: To convert an MOLE string to a VB HSZ string.
  1149.     Note:    This is a little out of place, but this module is
  1150.              common to all of the others.
  1151. */
  1152. HSZ GetMoleHsz(HCTL hCtl, MOLE mMole)
  1153. {
  1154.  static szBuffer[256];
  1155.  HSZ hszTemp;
  1156.  LPSTR lpTemp;
  1157.  char cChar;
  1158.  USHORT uLength;
  1159.  
  1160.  DEBUGIO((LPSTR)"GetMoleHsz() - Begin");
  1161.  
  1162.  if(mMole)
  1163.  {
  1164.   uLength = VBGetHlstrLen((HLSTR)mMole);
  1165.  
  1166. #ifdef DEBUG_BUILD
  1167.   wsprintf((LPSTR)szBuffer, (LPSTR)"uLength=%X", uLength);
  1168.   DEBUGIO((LPSTR)szBuffer);
  1169. #endif
  1170.  
  1171.   lpTemp = VBDerefHlstr((HLSTR)mMole);
  1172.   if(lpTemp)
  1173.   {
  1174.    lstrcpyn((LPSTR)szBuffer, lpTemp, uLength);
  1175.    szBuffer[uLength+1] = '\0';
  1176.    DEBUGIO((LPSTR)szBuffer);
  1177.    hszTemp=VBCreateHsz((_segment)hCtl, (LPSTR)szBuffer);
  1178.    DEBUGIO((LPSTR)"GetMoleHsz() - End - Built valid HSZ");
  1179.    return(hszTemp);
  1180.   }
  1181.  }
  1182.  
  1183.  cChar = '\0';
  1184.  hszTemp=VBCreateHsz((_segment)hCtl, (LPSTR)&cChar);
  1185.  DEBUGIO((LPSTR)"GetMoleHsz() - End - Returned an empty string!");
  1186.  return(hszTemp);
  1187. } /* GetMoleHsz() */
  1188.  
  1189.  
  1190. /* VOID GetMoleName(MOLE, LPSTR, int);
  1191.     Purpose: To convert an MOLE string to a C string.
  1192.     Note:    This is a little out of place, but this module is
  1193.              common to all of the others.
  1194. */
  1195. VOID GetMoleName(MOLE mMole, LPSTR lpString, int iSize)
  1196. {
  1197.  static szBuffer[256];
  1198.  LPSTR lpTemp;
  1199.  size_t stCount;
  1200.  
  1201.  //DEBUGIO((LPSTR)"GetMoleName() - Begin");
  1202.  
  1203.  if(!lpString) return;
  1204.  if(!iSize) return;
  1205.  
  1206.  if(mMole)
  1207.  {
  1208.   stCount = (size_t)VBGetHlstrLen((HLSTR)mMole);
  1209.   if(stCount > (size_t)iSize)
  1210.   {
  1211.    DEBUGIO((LPSTR)"GetMoleName() - I don't have enough room to hold it all!");
  1212.    stCount = (size_t)iSize;
  1213.   }
  1214.   lpTemp = VBDerefHlstr((HLSTR)mMole);
  1215.   if(lpTemp)
  1216.   {
  1217.    _fmemmove(lpString, lpTemp, stCount);
  1218.    //DEBUGIO((LPSTR)"GetMoleName() - End - Success!");
  1219.    return;
  1220.   }
  1221.  }
  1222.  
  1223.  *lpString = '\0';
  1224.  DEBUGIO((LPSTR)"GetMoleName() - End - Returned an empty string!");
  1225.  return;
  1226. } /* GetMoleName() */
  1227.  
  1228.  
  1229. /* VOID SetMole(MOLE, LPSTR);
  1230.     Purpose: To set the handed MOLE to the handed LPSTR.
  1231. */
  1232. VOID SetMole(LPMOLE pmMole, LPSTR lpString)
  1233. {
  1234.  HLOCAL hLocal;
  1235.  LPSTR lpTemp;
  1236.  
  1237.  DEBUGIO((LPSTR)"SetMole() - Begin");
  1238.  
  1239.  if(!lpString)
  1240.  {
  1241.   DEBUGIO((LPSTR)"SetMole() - End - lpString was NULL");
  1242.   return;
  1243.  }
  1244.  
  1245.  if(VBSetHlstr((LPHLSTR)pmMole, lpString, lstrlen(lpString) + 1))
  1246.  {
  1247.   DEBUGIO((LPSTR)"SetMole() - VBSetHlstr() failed!");
  1248.  }
  1249.  else
  1250.  {
  1251.   DEBUGIO((LPSTR)"SetMole() - VBSetHlstr() was successful!");
  1252.  }
  1253.  
  1254.  DEBUGIO((LPSTR)"SetMole() - End");
  1255.  return;
  1256. }   /* SetMole() */
  1257.  
  1258.  
  1259. /* MOLE AddMole(LPSTR);
  1260.     Purpose: To create a new MOLE for an LPSTR.
  1261. */
  1262. MOLE AddMole(LPSTR lpString)
  1263. {
  1264.  MOLE mTemp;
  1265.  
  1266.  //DEBUGIO((LPSTR)"AddMole() - Begin");
  1267.  
  1268.  mTemp = CreateMole(lpString , (USHORT)(lstrlen(lpString) + 1));
  1269.  
  1270.  //DEBUGIO((LPSTR)"AddMole() - End");
  1271.  return(mTemp);
  1272. }   /* AddMole() */
  1273.  
  1274.  
  1275. /* MOLE CreateMole(LPSTR, int);
  1276.     Purpose: To allow set length Mole's
  1277. */
  1278. MOLE CreateMole(LPSTR lpString, USHORT uLength)
  1279. {
  1280.  HLSTR hlStr;
  1281.  
  1282.  DEBUGIO((LPSTR)"CreateMole() - Begin");
  1283.  
  1284.  if(!lpString)
  1285.  {
  1286.   DEBUGIO((LPSTR)"CreateMole() - End - lpString was NULL");
  1287.   return((MOLE)0);
  1288.  }
  1289.  
  1290.  hlStr = VBCreateHlstr(lpString, uLength);
  1291.  
  1292.  if(hlStr)
  1293.  {
  1294.   DEBUGIO((LPSTR)"CreateMole() - VBCreateHlstr() Succeeded!");
  1295.  }
  1296.  else
  1297.  {
  1298.   DEBUGIO((LPSTR)"CreateMole() - VBCreateHlstr() Failed!");
  1299.  }
  1300.  
  1301.  DEBUGIO((LPSTR)"CreateMole() - End");
  1302.  return((MOLE)hlStr);
  1303. } /* CreateMole() */
  1304.  
  1305.  
  1306. /* VOID DeleteMole(LPMOLE);
  1307.     Purpose: To delete the handed MOLE
  1308. */
  1309. VOID DeleteMole(MOLE mMole)
  1310. {
  1311.  //DEBUGIO((LPSTR)"DeleteMole() - Begin");
  1312.  
  1313.  if(mMole)
  1314.  {
  1315.   VBDestroyHlstr((HLSTR)mMole);
  1316.   DEBUGIO((LPSTR)"DeleteMole() - End");
  1317.   return;
  1318.  }
  1319.  //DEBUGIO((LPSTR)"DeleteMole() - End - Mole was 0!");
  1320. } /* DeleteMole() */
  1321.  
  1322.  
  1323. /* END of Net.C */
  1324.